package com.atguigu.gmall.mq.receiver;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.mq.config.DeadLetterMqConfig;
import com.atguigu.gmall.mq.config.DelayedMqConfig;
import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * ClassName: MqReceiver
 * Package: com.atguigu.gmall.mq.receiver
 * Description:
 *
 * @Author 刘轩
 * @Create 2023-09-04 15:49
 * @Version 1.0
 */

@Component
public class MqReceiver {


    @Autowired
    private RedisTemplate redisTemplate;

    //监听信息  1. 初始化绑定关系！ 2。 监听消息
    @SneakyThrows
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue.confirm", durable = "true", autoDelete = "false"),
            exchange = @Exchange(value = "exchange.confirm"),
            key = {"routing.confirm"}
    ))
    public void getMsg(String msg, Message message, Channel channel) {
        try {
            System.out.println("接收:" + msg);
            System.out.println(new String(message.getBody()));
        } catch (Exception e) {
            //  //  手动签收 第一个参数表示：消息的标签 唯一表示 第二个参数表示是否批量确认！ 第三个参数：是否重回队列！
            //  channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
            //  如果消费不掉消息，则将消息写入记录表. insert into msg values ();
            // throw new RuntimeException(e);
            e.printStackTrace();
        }

        //  手动签收 第一个参数表示：消息的标签 唯一表示 第二个参数表示是否批量确认！
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    //  监听死信队列
    @SneakyThrows
    @RabbitListener(queues = DeadLetterMqConfig.queue_dead_2)
    public void getDeadMsg(String msg, Message message, Channel channel) {
        try {
            //  获取系统时间
            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            System.out.println(msg);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        //  手动签收
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

    //  监听延迟插件
    @SneakyThrows
    @RabbitListener(queues = DelayedMqConfig.queue_delay_1)
    public void getDelayMsg(String msg, Message message, Channel channel) {
        try {
            //  获取系统时间
            System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            //  判断
            if (!StringUtils.isEmpty(msg)) {
                System.out.println(msg);
                JSONObject jsonObject = JSON.parseObject(msg, JSONObject.class);
                String uuid = "";
                try {
                    //  保证消息幂等性
                    uuid = (String) jsonObject.get("uuid");
                    Boolean result = this.redisTemplate.opsForValue().setIfAbsent(uuid, uuid);
                    if (!result) {
                        //  说明存在
                        System.out.println("消息已被消费过...");
                        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                        return;
                    }
                    //  消费出现某种异常，int i = 1/0;
                    System.out.println("消费的内容：" + jsonObject.get("content"));
                } catch (IOException e) {
                    //  删除缓存的key
                    this.redisTemplate.delete(uuid);
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {

            e.printStackTrace();
        }
        //  手动签收
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}
